home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / DETH_SRC.ZIP / DMALIB.C < prev    next >
C/C++ Source or Header  |  1993-06-27  |  4KB  |  206 lines

  1.  
  2. /* Copyright 1993 by Peter Sprenger   Pete@amber.dinoco.de
  3.  *                   5014 Kerpen 3
  4.  *                   Germany
  5.  *
  6.  * Permission to use, copy, modify, and distribute this
  7.  * software and its documentation for any purpose and without
  8.  * fee is hereby granted, provided that the above copyright
  9.  * notice appear in all copies.  The author Peter Sprenger
  10.  * makes no representations about the suitability of this
  11.  * software for any purpose.  It is provided "as is" without
  12.  * express or implied warranty.
  13.  */
  14.  
  15.  
  16. #include <stddef.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <dos.h>
  20. #include "mydef.h"
  21. #include "dmalib.h"
  22.  
  23. static struct dma_op
  24. {
  25.     BYTE dmode;
  26.     BYTE page;
  27.     DWORD len;
  28.  
  29.     BYTE maskadr;
  30.     BYTE enable;
  31.     BYTE disable;
  32.  
  33.     BYTE flip;
  34.     BYTE adradr;
  35.     BYTE cntadr;
  36.     BYTE pageadr;
  37.     BYTE cmdadr;
  38.  
  39.     BYTE cmd;
  40. } dma_data[8];
  41.  
  42. static WORD dma_adr[8]={0,2,4,6,0xc0,0xc2,0xc4,0xc6};
  43. static WORD dma_cnt[8]={1,3,5,7,0xc1,0xc3,0xc5,0xc7};
  44. static WORD dma_page[8]={0x87,0x83,0x81,0x82,0x8f,0x8b,0x89,0x8a};
  45.  
  46. DWORD far2long(char far *adr)
  47. {
  48.     return(((DWORD)FP_SEG(adr)<<4)+FP_OFF(adr));
  49. }
  50.  
  51. WORD dma_set(DWORD adrl,DWORD len,int channel,BYTE mode)
  52. {
  53.     WORD subcount,adr;
  54.     DWORD lenl;
  55.     struct dma_op *ptr;
  56.     BYTE page;
  57.  
  58.     ptr=&dma_data[channel];
  59.  
  60.     lenl=len;
  61.  
  62.     if(channel>3)
  63.     {
  64.         adrl>>=1;
  65.         lenl>>=1;
  66.     }
  67.  
  68.     subcount=~(WORD)adrl+1;         /* calculate to page boundary */
  69.     if(lenl<subcount) subcount=lenl;
  70.  
  71.     adr=(WORD)adrl;
  72.     page=(BYTE)(adrl>>16);
  73.  
  74.     ptr->len=lenl-subcount; /* calc len for next event */
  75.     ptr->dmode=mode;
  76.     ptr->page=page+1;
  77.  
  78.     if(channel>3)    /* setup addresses */
  79.     {
  80.         ptr->maskadr=0xd4;
  81.         ptr->cmdadr=0xd6;
  82.         ptr->flip=0xd8;
  83.     }
  84.     else
  85.     {
  86.         ptr->maskadr=0xa;
  87.         ptr->cmdadr=0xb;
  88.         ptr->flip=0xc;
  89.     }
  90.     ptr->cmd=(BYTE)channel|mode;
  91.     ptr->enable=(BYTE)channel;
  92.     ptr->disable=(BYTE)channel|4;
  93.  
  94.     ptr->cntadr=dma_cnt[channel];
  95.     ptr->adradr=dma_adr[channel];
  96.     ptr->pageadr=dma_page[channel];
  97.  
  98.     asm cli;
  99.  
  100.     _DX=ptr->maskadr;
  101.     _AL=ptr->disable;
  102.     asm out dx,al;     /* disable channel */
  103.  
  104.     _DX=ptr->cmdadr;
  105.     _AL=ptr->cmd;
  106.     asm out dx,al;     /* set dma mode */
  107.  
  108.     _DX=ptr->flip;
  109.     asm out dx,al;     /* reset flipflop */
  110.  
  111.     _DX=ptr->adradr;
  112.     asm mov ax,adr;
  113.     asm out dx,al;
  114.     asm mov al,ah;
  115.     asm out dx,al;                /* set address */
  116.  
  117.     _DX=ptr->pageadr;
  118.     asm mov al,page;
  119.     asm out dx,al;     /* set page */
  120.  
  121.     _DX=ptr->flip;
  122.     asm out dx,al;     /* reset flipflop */
  123.  
  124.     _DX=ptr->cntadr;
  125.     asm mov ax,subcount;
  126.     asm dec ax;                /* decrement length */
  127.     asm out dx,al;
  128.     asm mov al,ah;
  129.     asm out dx,al;                /* set length */
  130.  
  131.     _DX=ptr->maskadr;
  132.     _AL=ptr->enable;
  133.     asm out dx,al;     /* enable channel */
  134.  
  135.     asm sti
  136.  
  137.     return(subcount);
  138. }
  139.  
  140. WORD dma_next(int channel)
  141. {
  142.     WORD subcount;
  143.     DWORD len;
  144.     struct dma_op *ptr;
  145.  
  146.     ptr=&dma_data[channel];
  147.     len=ptr->len;
  148.     if(!len) return(0); /* dma done */
  149.     if(len>65536L)
  150.     {
  151.         ptr->len-=65536;
  152.         subcount=0;
  153.     }
  154.     else
  155.     {
  156.         ptr->len=0;
  157.         subcount=(WORD)len;
  158.     }
  159.  
  160.     asm cli;
  161.  
  162.     _DX=ptr->maskadr;
  163.     _AL=ptr->disable;
  164.     asm out dx,al;     /* disable channel */
  165.  
  166.     _DX=ptr->cmdadr;
  167.     _AL=ptr->cmd;
  168.     asm out dx,al;     /* set dma mode */
  169.  
  170.     _DX=ptr->flip;
  171.     asm out dx,al;     /* reset flipflop */
  172.  
  173.     _DX=ptr->adradr;
  174.     asm mov al,0
  175.     asm out dx,al;
  176.     asm out dx,al;                /* set address NULL */
  177.  
  178.     _DX=ptr->pageadr;
  179.     _AL=ptr->page++;
  180.     asm out dx,al;     /* set page */
  181.  
  182.     _DX=ptr->flip;
  183.     asm out dx,al;     /* reset flipflop */
  184.  
  185.     _DX=ptr->cntadr;
  186.     asm mov ax,subcount;
  187.     asm dec ax;                /* decrement length */
  188.     asm out dx,al;
  189.     asm mov al,ah;
  190.     asm out dx,al;                /* set length */
  191.  
  192.     _DX=ptr->maskadr;
  193.     _AL=ptr->enable;
  194.     asm out dx,al;     /* enable channel */
  195.  
  196.     asm sti
  197.     return(subcount);
  198. }
  199.  
  200. long dma_len(int channel)
  201. {
  202.     return(dma_data[channel].len);
  203. }
  204.  
  205.  
  206.